#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "sqlite3.h"

/**
 * 定义引用
 */
typedef struct {
    sqlite3* pt;
} RefSqlite3Handler;

typedef struct {
    sqlite3_stmt* pt;
} RefSqlite3StmtHandler;

/** 打开数据库连接 */
int openSqlite3(RefSqlite3Handler* pDbHandler, char* zFilename) {
    return sqlite3_open(zFilename, &(pDbHandler->pt));
}

/** 关闭数据库连接 */
int closeSqlite3(RefSqlite3Handler* pDbHandler) {
    return sqlite3_close(pDbHandler->pt);
}

/** 获取数据库错误消息 */
const char* getSqlite3ErrMsg(RefSqlite3Handler* pDbHandler) {
    return sqlite3_errmsg(pDbHandler->pt);
}

/** 内存释放 */
void freeSqlite3(void* obj) {
    sqlite3_free(obj);
}

/** 执行 SQL (无回调) */
int execSqlite3(RefSqlite3Handler* pDbHandler, const char *sql, char **errmsg) {
    return sqlite3_exec(pDbHandler->pt, sql, 0, 0, errmsg);
}

/* 执行查询 */
int getTableSqlite3(
  RefSqlite3Handler* pDbHandler,
  const char *zSql,     /* SQL to be evaluated */
  char ***pazResult,    /* Results of the query */
  int *pnRow,           /* Number of result rows written here */
  int *pnColumn,        /* Number of result columns written here */
  char **pzErrmsg       /* Error msg written here */
) {
    return sqlite3_get_table(pDbHandler->pt, zSql, pazResult, pnRow, pnColumn, pzErrmsg);
}

/* 释放查询结果 */
void freeTableSqlite3(char **result) {
    sqlite3_free_table(result);
}

/**
 * 创建预执行语句
 */
int createSqlite3Statement(
  RefSqlite3Handler* pDbHandler,
  const char *zSql,       /* SQL statement, UTF-8 encoded */
  int nByte,              /* Maximum length of zSql in bytes. */
  RefSqlite3StmtHandler* pStmtHandler,  /* OUT: Statement handle */
  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
) {
    return sqlite3_prepare_v2(pDbHandler->pt, zSql, nByte, &(pStmtHandler->pt), pzTail);
}

/**
 * 销毁执行语句
 */
int finalizeSqlite3Statement(RefSqlite3StmtHandler* pStmtHandler) {
    return sqlite3_finalize(pStmtHandler->pt);
}

/** 绑定预执行参数字段 */
int bindSqlite3Null(RefSqlite3StmtHandler* pStmtHandler, int iCol) {
    return sqlite3_bind_null(pStmtHandler->pt, iCol);
}

int bindSqlite3Int(RefSqlite3StmtHandler* pStmtHandler, int iCol, int value) {
    return sqlite3_bind_int(pStmtHandler->pt, iCol, value);
}

int bindSqlite3Int64(RefSqlite3StmtHandler* pStmtHandler, int iCol, sqlite3_int64 value) {
    return sqlite3_bind_int64(pStmtHandler->pt, iCol, value);
}

int bindSqlite3Double(RefSqlite3StmtHandler* pStmtHandler, int iCol, double value) {
    return sqlite3_bind_double(pStmtHandler->pt, iCol, value);
}

int bindSqlite3Text(RefSqlite3StmtHandler* pStmtHandler, int iCol, const char *zData, int nData) {
    // SQLITE_STATIC: 静态分配(即在绑定过程中不需要释放或管理它)
    // SQLITE_TRANSIENT: 拷贝输传入的字符(即复制这个值，并在适当的时候释放它)
    return sqlite3_bind_text(pStmtHandler->pt, iCol, zData, nData, SQLITE_TRANSIENT);
}

int bindSqlite3Blob(RefSqlite3StmtHandler* pStmtHandler, int iCol, const void *zData, int nData) {
    return sqlite3_bind_blob(pStmtHandler->pt, iCol, zData, nData, SQLITE_STATIC);
}


/** 绑定后的执行 */
int stepSqlite3(RefSqlite3StmtHandler* pStmtHandler) {
    return sqlite3_step(pStmtHandler->pt);
}

/** 列字段值查询 */
int columnSqlite3Int(RefSqlite3StmtHandler* pStmtHandler, int iCol) {
    return sqlite3_column_int(pStmtHandler->pt, iCol);
}

sqlite3_int64 columnSqlite3Int64(RefSqlite3StmtHandler* pStmtHandler, int iCol) {
    return sqlite3_column_int64(pStmtHandler->pt, iCol);
}

double columnSqlite3Double(RefSqlite3StmtHandler* pStmtHandler, int iCol) {
    return sqlite3_column_double(pStmtHandler->pt, iCol);
}
const unsigned char *columnSqlite3Text(RefSqlite3StmtHandler* pStmtHandler, int iCol) {
    return sqlite3_column_text(pStmtHandler->pt, iCol);
}
const void *columnSqlite3Blob(RefSqlite3StmtHandler* pStmtHandler, int iCol) {
    return sqlite3_column_blob(pStmtHandler->pt, iCol);
}

/**
 * 指定列字节长度
 */
int countByteSqlite3Column(RefSqlite3StmtHandler* pStmtHandler, int iCol) {
    return sqlite3_column_bytes(pStmtHandler->pt, iCol);
}

/** 列返回类型 */
int typeSqlite3Column(RefSqlite3StmtHandler* pStmtHandler, int iCol) {
    return sqlite3_column_type(pStmtHandler->pt, iCol);
}

/** 列名称 */
const char* nameSqlite3Column(RefSqlite3StmtHandler* pStmtHandler, int iCol) {
    return sqlite3_column_name(pStmtHandler->pt, iCol);
}

/** 统计查询的列数  */
int countSqlite3Column(RefSqlite3StmtHandler* pStmtHandler) {
    return sqlite3_column_count(pStmtHandler->pt);
}

int resetSqlite3Statement(RefSqlite3StmtHandler* pStmtHandler) {
    return sqlite3_reset(pStmtHandler->pt);
}

int clearSqlite3BindStatement(RefSqlite3StmtHandler* pStmtHandler) {
    return sqlite3_clear_bindings(pStmtHandler->pt);
}

/** 清除绑定并重置 */
int resetClearSqlite3Statement(RefSqlite3StmtHandler* pStmtHandler) {
    int rc = sqlite3_reset(pStmtHandler->pt);
    if (rc != SQLITE_OK) {
        return rc;
    }
    return sqlite3_clear_bindings(pStmtHandler->pt);
}

int getChangeRowSqlite3(RefSqlite3Handler* pDbHandler) {
    return sqlite3_changes(pDbHandler->pt);
}

/** 获取最后一个插入的主键ID (使用 int 接)
 */
int getLastInsertRowIdRowSqlite3(RefSqlite3Handler* pDbHandler) {
    return sqlite3_last_insert_rowid(pDbHandler->pt);
}